package com.imjohn.controller;

import com.imjohn.entity.WxPublic;
import com.imjohn.service.WxPublicService;
import com.imjohn.util.respUtil;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api")
public class WxShareController {
    @Autowired
    public WxPublicService wxPublicService;
    private static final String AppID = "wx8b6f7ec37487ab03"; //开发者ID
    private static final String AppSecret = "ca30dbdee5aa5a2ea60bf43415f022a7"; //开发者密码
    private static String access_token = ""; //调用接口的凭证 2个小时后就会过期需要重新获取 一天最多获取2千次
    private static String jsapi_ticket = ""; //jsapi_ticket的有效时间也是2个小时  获取该参数需要通过access_token
    private static String hasSucccess = "0"; // 公众号自定义菜单配置成功标志

    @RequestMapping("/share")
    public WxPublic Share (@RequestBody HashMap wxmap){
        String url = (String) wxmap.get("url");//即调用 JS-SDK的网址
        WxPublic wxpublic = (WxPublic) wxPublicService.hasSign();
        Long nowtime = System.currentTimeMillis()/1000;//获取当前的时间戳
        if (Integer.parseInt(wxpublic.getTimestamp()) <= nowtime) {//如果过期时间小于 当前的时间就证明过期了
            WxPublic wxShare = getWxShare(url);//随机串、签名的时间戳、签名字符串
            return wxShare;
        } else {
            return wxpublic;
        }
    }

    @RequestMapping("/setWx")
    public Map setWx (@RequestBody HashMap map){

        WxPublic wxpublic = (WxPublic) wxPublicService.hasSign();
        //打开浏览器，创建HTTPClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        //第一步 判断access_token 与 jsapi_ticket是否过期 如果过期了就重新获取

        //通过appid和appsecret，就可以向微信平台来换取access_token
        String token_access_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WxShareController.AppID+"&secret="+WxShareController.AppSecret;
        HttpGet httpGet = new HttpGet(token_access_url);
        CloseableHttpResponse response = null;//按回车，发起请求

        try {
            response = httpClient.execute(httpGet);
            //解析响应 判断状态码是否是200
            if (response.getStatusLine().getStatusCode()==200){
                HttpEntity httpEntity = response.getEntity();//获取响应消息实体
                String body = EntityUtils.toString(httpEntity);//获取返回的消息文本
                JSONObject jsonObject = JSONObject.fromObject(body);//将消息文本解析成json
                String access_token = (String) jsonObject.get("access_token");
                WxShareController.access_token = access_token;
            }
            String setWx_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + WxShareController.access_token;
            HttpPost post = new HttpPost(setWx_url);
            post.setHeader("content-type","application/json");
            StringEntity entity = new StringEntity(map.toString(),"UTF-8");
            post.setEntity(entity);
            if (response.getStatusLine().getStatusCode()==200){//解析响应 判断状态码是否是200
                System.out.printf("response", response);
                WxShareController.hasSucccess = "1";
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            try {response.close();} catch (IOException e) {e.printStackTrace();}
            try {httpClient.close();} catch (IOException e) {e.printStackTrace();}
        }
        if (WxShareController.hasSucccess == "1") {
            Map res = new HashMap();
            res.put("msg", "配置成功!");
            return respUtil.respSuccessHash(res);
        } else {
            String fReason = "配置失败!";
            return respUtil.respFailer(fReason);
        }
    }


    //获取微信分享的重要信息
    public WxPublic getWxShare(String url){//url 即为访问网站的url
        WxPublic wxPublic = new WxPublic(); //用于保存微信分享所需要的参数

        //打开浏览器，创建HTTPClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        //第一步 判断access_token 与 jsapi_ticket是否过期 如果过期了就重新获取

            //通过appid和appsecret，就可以向微信平台来换取access_token
            String token_access_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WxShareController.AppID+"&secret="+WxShareController.AppSecret;
            HttpGet httpGet = new HttpGet(token_access_url);
            CloseableHttpResponse response = null;//按回车，发起请求
            try {
                response = httpClient.execute(httpGet);
                //解析响应 判断状态码是否是200
                if (response.getStatusLine().getStatusCode()==200){
                    HttpEntity httpEntity = response.getEntity();//获取响应消息实体
                    String body = EntityUtils.toString(httpEntity);//获取返回的消息文本
                    JSONObject jsonObject = JSONObject.fromObject(body);//将消息文本解析成json
                    String access_token = (String) jsonObject.get("access_token");
                    WxShareController.access_token = access_token;
                }
                //第二步 通过access_token，向微信平台索取一个jsapi_ticket
                String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+WxShareController.access_token+"&type=jsapi";
                httpGet = new HttpGet(jsapi_ticket_url);
                response = httpClient.execute(httpGet);
                if (response.getStatusLine().getStatusCode()==200){//解析响应 判断状态码是否是200
                    HttpEntity httpEntity = response.getEntity();//获取响应消息实体
                    String body = EntityUtils.toString(httpEntity);//获取返回的消息文本
                    JSONObject jsonObject = JSONObject.fromObject(body);//将消息文本解析成json
                    String errmsg = (String) jsonObject.get("errmsg");
                    if(errmsg.trim().equals("ok")){
                        String jsapi_ticket = (String) jsonObject.get("ticket");
                        WxShareController.jsapi_ticket = jsapi_ticket;

                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关闭资源
                try {response.close();} catch (IOException e) {e.printStackTrace();}
                try {httpClient.close();} catch (IOException e) {e.printStackTrace();}
            }



        //第三步 获得jsapi_ticket之后，就可以生成JS-SDK权限验证的签名了。
        Long timestamp = System.currentTimeMillis()/1000;//用于签名的时间戳 单位为秒
        String nonceStr = UUID.randomUUID().toString(); //获得随机串

        //注意这里参数名必须全部小写，且必须有序
        String string1 = "jsapi_ticket=" + WxShareController.jsapi_ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url;

        String signature = ""; //签名字符串
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
            messageDigest.reset(); //reset()的必要性只表明getInstance()不进行初始化.
            messageDigest.update(string1.getBytes("UTF-8"));

            Formatter formatter = new Formatter();
            for (byte b : messageDigest.digest()) formatter.format("%02x", b);//字节数组转换为十六进制字符串

            signature = formatter.toString();//签名字符串
            formatter.close();
        }catch (Exception e){}


        wxPublic.setNonceStr(nonceStr);//随机串
        wxPublic.setAccess_token(WxShareController.access_token);
        wxPublic.setJsapi_ticket(WxShareController.jsapi_ticket);
        wxPublic.setTimes(timestamp.toString());
        Long timestamp2 = System.currentTimeMillis()/1000 + 5400;
        wxPublic.setTimestamp(timestamp2.toString());//签名的时间戳
        wxPublic.setSignature(signature);//签名字符串
        wxPublic.setAppId(AppID);
        wxPublicService.updateWxSign(wxPublic);

        return wxPublic;
    }

}
